/*
 * Copyright (C) 2015 The Sven Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cc.core.os;

import android.app.ActivityManager;
import android.content.Context;
import android.os.*;
import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.List;

@SuppressWarnings("unused")
public class Usage {

    private static final String TAG = "Usage";

    /**
     * 获取内存信息
     * @return @see #MemoryInfo.class
     */
    public static MemoryInfo getMemoryInfo() {
        try {

            Class processClass = Class.forName("android.os.Process");
            Class parameterTypes[] = new Class[]{String.class, String[].class, long[].class};

            Method readFunc = processClass.getMethod("readProceLines", parameterTypes);

            final String[] mMemInfoFields = new String[]{"MemTotal:", "MemFree:", "Buffers:", "Cached:"};

            long[] mMemInfoSizes = new long[mMemInfoFields.length];
            mMemInfoSizes[0] = 30;
            mMemInfoSizes[1] = -30;

            Object argument[] = new Object[3];
            argument[0] = "/proc/meminfo";
            argument[1] = mMemInfoFields;
            argument[2] = mMemInfoSizes;

            if (readFunc != null) {

                readFunc.invoke(null, argument);
                MemoryInfo mem = new MemoryInfo();

                mem.memTotal = mMemInfoSizes[0] / 1024;
                mem.memFree = mMemInfoSizes[1] / 1024;
                mem.buffers = mMemInfoSizes[2] / 1024;
                mem.cached  = mMemInfoSizes[3] / 1024;
                return mem;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取最大内存
     * @return kb
     */
    public static long getTotalMemory() {
        String str1 = "/proc/meminfo";// 系统内存信息文件
        String str2;
        String[] arrayOfString;
        long initial_memory = 0;

        try {
            FileReader localFileReader = new FileReader(str1);
            BufferedReader localBufferedReader = new BufferedReader(
                    localFileReader, 8192);
            str2 = localBufferedReader.readLine();// 第一行，系统总内存大小

            arrayOfString = str2.split("\\s+");

            initial_memory = Integer.valueOf(arrayOfString[1]) * 1024; // 单位kb
            localBufferedReader.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

        return initial_memory;
    }

    /**
     * 获取可用内存
     * @return kb
     */
    public static long getAvailMemory(Context context) {// 获取android当前可用内存大小
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        am.getMemoryInfo(mi);

        return mi.availMem;
    }

    /**
     * 获取磁盘信息
     * @return @see #DeskInfo.class
     */
    @SuppressWarnings("deprecation")
    public static DeskInfo getTotalDesk() {
        File root = Environment.getRootDirectory();
        StatFs sf = new StatFs(root.getPath());
        long blockSize = sf.getBlockSize();
        long blockCount = sf.getBlockCount();
        long availCount = sf.getAvailableBlocks();

        DeskInfo desk = new DeskInfo();

        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            File sdcardDir = Environment.getExternalStorageDirectory();
            StatFs exSF = new StatFs(sdcardDir.getPath());
            long exBlockSize = exSF.getBlockSize();
            long exBlockCount = exSF.getBlockCount();
            long exAvailCount = exSF.getAvailableBlocks();

            desk.eAvail = exAvailCount * exBlockSize / 1024;
            desk.eTotal = exBlockCount * exBlockSize / 1024;
        }

        desk.iTotal = blockCount * blockSize / 1024;
        desk.iAvail = availCount * blockSize / 1024;
        return desk;
    }

    /**
     * 清理内存
     * @param context context
     */
    public static void cleanMemory(Context context) {
        ActivityManager am;
        am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfoList;
        runningAppProcessInfoList = am.getRunningAppProcesses();

        ActivityManager.RunningAppProcessInfo runningAppProcessInfo;
        for (int i = 0, count = runningAppProcessInfoList.size(); i < count; i++) {

            runningAppProcessInfo = runningAppProcessInfoList.get(i);
            String processName = runningAppProcessInfo.processName;
            am.killBackgroundProcesses(processName);
            System.gc();

        }
    }

    /**
     *  杀死进程
     * @param pid precess id
     */
    public static void killProcessByProcess(int pid) {
        android.os.Process.killProcess(pid);
    }

    /**
     *  杀死进程
     * @param pid precess id
     */
    public static void killProcessByACmd(int pid) {

        String cmd = "adb shell kill -9 " + pid;

        try {

            java.lang.Process process = Runtime.getRuntime().exec(cmd);
            InputStreamReader isr = new InputStreamReader(process.getInputStream());
            BufferedReader br = new BufferedReader(isr);

            String line;
            while ((line = br.readLine()) != null) {
                Log.d(TAG, line);
            }

            br.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *  杀死进程
     * @param pid precess id
     */
    public static void killProcessBySu(int pid) {
        try {
            java.lang.Process process = Runtime.getRuntime().exec("su");
            String cmd = "kill -9 " + pid;
            System.out.println("-------> cmd = " + cmd);
            process.getOutputStream().write(cmd.getBytes());
            if ((process.waitFor() != 0)) {
                System.out.println("-------> su.waitFor()!= 0");
            } else {
                System.out.println("-------> su.waitFor()== 0");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 内存信息
     * 大小单位 kb
     */
    public static class MemoryInfo
    {
        public float memTotal;
        public float memFree;
        public float buffers;
        public float cached;
    }

    /**
     * 磁盘信息
     * 大小单位 kb
     */
    public static class DeskInfo
    {
        public float iTotal;
        public float iAvail;
        public float eTotal;
        public float eAvail;
    }
}
